<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: packages/map/src/map.vue</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: packages/map/src/map.vue</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>&lt;template>
  &lt;div class="xdh-map" ref="map" :style="styles">
    &lt;slot>&lt;/slot>
  &lt;/div>
&lt;/template>

&lt;script>
/**
 *  XdhMap 组件
 *  @module xdh-map
 *  @description 基于ol/Map的封装，支持ol/Map所提供的所有事件，相关事件参考openlayers文档，可以通过this.map 访问ol/Map实例
 *  @example
 *
 *  &lt;xdh-map :center="[120, 30]">&lt;/xdh-map>
 *
 *  import {XdhMap} from 'xdh-map'
 *  export default {
 *    components: {
 *      XdhMap
 *    }
 *  }
 */

import Map from 'ol/Map'
import View from 'ol/View'
import VectorLayer from 'ol/layer/Vector'
import VectorSource from 'ol/source/Vector'
import { set as setLayerConfig } from 'utils/setting'
import { createLayer } from 'utils/layers'
import { convertFromWgs84 } from 'utils/convert'
/*
   地图支持以下事件：
    change        (module:ol/events/Event~Event)    - Generic change event. Triggered when the revision counter is increased.change:layerGroup (module:ol/Object.ObjectEvent)
    change:size   (module:ol/Object.ObjectEvent)
    change:target (module:ol/Object.ObjectEvent)
    change:view   (module:ol/Object.ObjectEvent)
    click         (module:ol/MapBrowserEvent~MapBrowserEvent) - A click with no dragging. A double click will fire two of this.
    dblclick      (module:ol/MapBrowserEvent~MapBrowserEvent) - A true double click, with no dragging.
    moveend       (module:ol/MapEvent~MapEvent) - Triggered after the map is moved.
    movestart     (module:ol/MapEvent~MapEvent) - Triggered when the map starts moving.
    pointerdrag   (module:ol/MapBrowserEvent~MapBrowserEvent) - Triggered when a pointer is dragged.
    pointermove   (module:ol/MapBrowserEvent~MapBrowserEvent) - Triggered when a pointer is moved. Note that on touch devices this is triggered when the map is panned, so is not the same as mousemove.
    postcompose   (module:ol/render/Event~RenderEvent)
    postrender    (module:ol/MapEvent~MapEvent) - Triggered after a map frame is rendered.
    precompose    (module:ol/render/Event~RenderEvent)
    propertychange (module:ol/Object.ObjectEvent) - Triggered when a property is changed.
    rendercomplete (module:ol/render/Event~RenderEvent) - Triggered when rendering is complete, i.e. all sources and tiles have finished loading for the current viewport, and all tiles are faded in.
    singleclick    (module:ol/MapBrowserEvent~MapBrowserEvent) - A true single click with no dragging and no double click. Note that this event is delayed by 250 ms to ensure that it is not a double click.
  */

/**
 * Slots 插槽
 * @member slots
 * @property {String} [default] 默认插槽，覆盖物组件
 */

export default {
  name: 'XdhMap',

  /**
   * Props 参数
   * @member props
   * @property {Number} [minZoom=1] 最小缩放层级
   * @property {Number} [maxZoom=20] 最大缩放层级
   * @property {Number} [zoom=10] 初始化缩放层级
   * @property {Number[]} [center] 初始化中心经纬度
   * @property {String} [type=OSM] 初始化图层瓦片地图类型, 默认可选值：OSM、Baidu、Google、Amap、SuperMap、Founder、TDT
   * @property {Object} [layerConfig] 图层瓦片服务配置
   * @property {String} [coordType=WGS84] 地图的坐标类型,可选类型：'BD09'(百度地图坐标系) ，'WGS84'(1984年世界大地坐标系统) ，'GCJ02'(火星坐标系)
   */

  props: {
    // 最小缩放
    minZoom: {
      type: Number,
      default: 1
    },
    // 最大缩放
    maxZoom: {
      type: Number,
      default: 20
    },
    // 初始化缩放层级
    zoom: {
      type: Number,
      default: 10
    },
    // 初始化中心经纬度
    center: {
      type: Array,
      default() {
        return [120, 30]
      }
    },
    // 初始化图层瓦片地图类型
    type: {
      type: String,
      default: 'TDT'
    },
    // 图层瓦片服务配置
    layerConfig: {
      type: Object,
      default() {
        return {}
      }
    },
    // 地图的坐标类型  BD09(百度地图坐标系) | WGS84(1984年世界大地坐标系统) | GCJ02(火星坐标系)
    coordType: {
      type: String,
      default: 'WGS84'
    }
  },
  provide() {
    return {
      coordType: this.coordType
    }
  },
  data() {
    return {
      // 鼠标形状
      cursor: null
    }
  },
  computed: {
    styles() {
      return {
        cursor: this.cursor
      }
    }
  },
  methods: {
    _mouseHandler(feature) {
      // 鼠标移出
      if (this.featureAtPixel &amp;&amp; !feature) {
        this.$emit('mouseleave', this.featureAtPixel)
      }
      // 鼠标移入
      if (!this.featureAtPixel &amp;&amp; feature) {
        this.$emit('mouseenter', feature)
      }

      if (this.featureAtPixel &amp;&amp; feature &amp;&amp; this.featureAtPixel !== feature) {
        this.$emit('mouseleave', this.featureAtPixel)
        this.$emit('mouseenter', feature)
      }
      this.featureAtPixel = feature
    },
    /**
     * 图形事件处理句柄
     * @private
     */
    _eventHandler(e) {
      const feat = this.getFeatureAtPixel(e.pixel)
      if (!feat) return
      const array = this._featureEvents[e.type] || []
      const item = array.find(item => item.feature === feat)
      item &amp;&amp; item.listener(e, item.feature)
    },
    /**
     * 绑定图形事件
     * @private
     * @param {string} type 事件类型名称
     * @param {FeatureClass} feature 图形实例
     * @param {Function} listener 事件句柄
     * @param {number} uid 图形所属的Vue实例id
     */
    _bind(type, feature, listener, uid) {
      // 图形的事件需要地图图层转发，为提高性能，共享图层事件
      // 相同的事件名称只注册一次
      let typeEvents = this._featureEvents[type]
      if (!typeEvents) {
        this._featureEvents[type] = []
        this.map.on(type, this._eventHandler)
      }
      this._featureEvents[type].push({ type, feature, listener, uid })
    },
    /**
     * 给子组件的图形绑定事件
     * @method bindEvents
     * @param {VueComponent} vm 子组件实例
     */
    bindEvents(vm) {
      if (!this.map || !vm.feature) return
      const listeners = vm.$listeners
      Object.keys(listeners)
        .filter(key => !['mouseenter', 'mouseleave'].includes(key))
        .forEach(key => {
          this._bind(key, vm.feature, listeners[key], vm._uid)
        })
    },
    /**
     * 给子组件的图形销毁事件
     * @method unbindEvents
     * @param {VueComponent} vm 子组件实例
     */
    unbindEvents(vm) {
      if (!this.map) return
      const listeners = vm.$listeners
      const uid = vm._uid
      Object.keys(listeners).forEach(key => {
        const array = this._featureEvents[key] || []
        array.splice(array.findIndex(item => item.uid === uid), 1)
        if (array.length === 0) {
          delete this._featureEvents[key]
          this.map.un(key, this._eventHandler)
        }
      })
    },
    /**
     * 创建矢量图层，只会创建一个图层，已创建即复用
     * @method createVectorLayer
     * @param {ol/Featrue} [feature] 图形实例, 可选，如传图形，创建图层并且把图形加入到图层中
     * @return {ol/layer/Vector} vectorLayer 图层实例
     */
    createVectorLayer(feature) {
      if (this.vectorLayer) {
        return this.vectorLayer
      }
      let vectorSource = new VectorSource()
      feature &amp;&amp; vectorSource.addFeature(feature)
      this.vectorLayer = new VectorLayer({
        source: vectorSource
      })
      this.map.addLayer(this.vectorLayer)
      return this.vectorLayer
    },
    /**
     * 在地图上添加图形, 图形加入到矢量图层
     * @method addFeature
     * @param {ol/Feature} feature 图形实例
     */
    addFeature(feature) {
      // 共享矢量图层，把所有图形就加入同一个图层
      if (this.vectorLayer) {
        const source = this.vectorLayer.getSource()
        source.addFeature(feature)
      } else {
        this.createVectorLayer(feature)
      }
    },
    /**
     * 删除图形
     * @method removeFeature
     * @param {ol/Feature} feature 图形实例
     */
    removeFeature(feature) {
      if (!this.vectorLayer) return
      const source = this.vectorLayer.getSource()
      source.removeFeature(feature)
    },
    /**
     * 根据地图上的像素位置获取图形对象
     * @method getFeatureAtPixel
     * @param  {Number[]} pixel 位置像素 [x,y]
     * @return {module:ol/Feature|module:ol/render/Feature|*}
     */
    getFeatureAtPixel(pixel) {
      return this.map.forEachFeatureAtPixel(pixel, function(feature) {
        return feature
      })
    },
    /**
     * 切换地图类型
     * @method changeType
     * @param {string} type 地图类型，如： Baidu / Amap / OSM
     */
    changeType(type) {
      if (!type) return

      const layers = this.map.getLayers().getArray()
      const tileLayer = layers.find(layer => layer.type === 'TILE')
      if (tileLayer) {
        this.map.removeLayer(tileLayer)
        tileLayer.disposeInternal()
      }
      const newLayers = [].concat(createLayer(type))
      newLayers.forEach(layer => {
        this.map.addLayer(layer)
      })
      /**
       * 地图类型切换时触发
       * @event changeType
       * @param {String} type
       */
      this.$emit('changeType', type)
    },
    /**
     * 重置地图尺寸，当容器的尺寸变化后需要执行resize
     * @method resize
     */
    resize() {
      this.map.updateSize()
    },
    /**
     * 设置地图缩放等级
     * @method zoomTo
     * @param {Number} level 等级数值
     */
    zoomTo(level) {
      const view = this.map.getView()
      view.animate({
        zoom: Number.parseInt(level)
      })
    },

    /**
     * 逐步放大
     * @method zoomIn
     */
    zoomIn() {
      const view = this.map.getView()
      this.zoomTo(view.getZoom() + 1)
    },

    /**
     * 逐步缩小
     *  @method zoomOut
     */
    zoomOut() {
      const view = this.map.getView()
      this.zoomTo(view.getZoom() - 1)
    },
    /**
     * 移动到指定经纬度居中
     * @method moveTo
     * @param {Number[]} loc 经纬度数组
     */
    moveTo(loc) {
      const view = this.map.getView()
      view.animate({
        center: loc
      })
    },
    /**
     * 设置鼠标形状
     * @method setCursor
     * @param {Event} e 事件对象
     */
    setCursor(e) {
      const feature = this.getFeatureAtPixel(e.pixel)
      if (feature &amp;&amp; feature._vm &amp;&amp; feature._vm.cursor) {
        this.cursor = feature._vm.cursor
      } else {
        this.cursor = null
      }
      this._mouseHandler(feature)
    }
  },
  created() {
    // 标记是地图组件
    this.isMap = true
    this.featureAtPixel = null

    /**
     * 图形绑定的事件集合，存储格式：
     * { click: [{type, feature, listener, uid}, ...], movestart: [..]}
     * type: 事件类型
     * feature：触发的图形对象
     * listener： Vue组件绑定的事件句柄
     * uid: Vue组件实例id
     */
    this._featureEvents = {}

    // 初始化图层瓦片服务配置
    setLayerConfig(this.layerConfig || {})
  },
  mounted() {
    const layers = [].concat(createLayer(this.type))
    const view = new View({
      projection: 'EPSG:4326',
      center: this.center,
      zoom: this.zoom,
      maxZoom: this.maxZoom,
      minZoom: this.minZoom
    })
    this.map = new Map({
      layers: layers,
      target: this.$refs.map,
      view: view,
      // 删除默认的控件
      controls: []
    })

    /**
     * 地图初始化完成
     * @event ready
     * @param {ol/Map} map ol地图实例
     * @param {VueComponent} mv Vue组件实例
     */
    this.$emit('ready', this.map, this)

    // 绑定地图事件
    Object.keys(this.$listeners).forEach(key => {
      this.map.on(key, e => {
        if (e.coordinate) {
          let coordinate = convertFromWgs84(this.coordType, e.coordinate)
          e.convert = {
            coordinate: coordinate
          }
        }
        this.$listeners[key](e)
      })
    })

    // 设置子图形的鼠标形状
    this.map.on('pointermove', this.setCursor)
  },
  beforeDestroy() {
    // 销毁地图事件
    if (this.map) {
      Object.keys(this.$listeners).forEach(key => {
        this.map.un(key, this.$listeners[key])
      })
      this.map.un('pointermove', this.setCursor)
      // 销毁地图
      this.map.disposeInternal()
    }
  }
}
&lt;/script>

</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-xdh-map.html">xdh-map</a></li><li><a href="module-xdh-map-circle.html">xdh-map-circle</a></li><li><a href="module-xdh-map-draw.html">xdh-map-draw</a></li><li><a href="module-xdh-map-echarts.html">xdh-map-echarts</a></li><li><a href="module-xdh-map-heat.html">xdh-map-heat</a></li><li><a href="module-xdh-map-html.html">xdh-map-html</a></li><li><a href="module-xdh-map-icon.html">xdh-map-icon</a></li><li><a href="module-xdh-map-image.html">xdh-map-image</a></li><li><a href="module-xdh-map-line.html">xdh-map-line</a></li><li><a href="module-xdh-map-mask.html">xdh-map-mask</a></li><li><a href="module-xdh-map-measure.html">xdh-map-measure</a></li><li><a href="module-xdh-map-overview.html">xdh-map-overview</a></li><li><a href="module-xdh-map-placement.html">xdh-map-placement</a></li><li><a href="module-xdh-map-pointer.html">xdh-map-pointer</a></li><li><a href="module-xdh-map-polygon.html">xdh-map-polygon</a></li><li><a href="module-xdh-map-popup.html">xdh-map-popup</a></li><li><a href="module-xdh-map-rectangle.html">xdh-map-rectangle</a></li><li><a href="module-xdh-map-scatter.html">xdh-map-scatter</a></li><li><a href="module-xdh-map-text.html">xdh-map-text</a></li><li><a href="module-xdh-map-track.html">xdh-map-track</a></li><li><a href="module-xdh-map-type.html">xdh-map-type</a></li><li><a href="module-xdh-map-zoom.html">xdh-map-zoom</a></li></ul><h3>Classes</h3><ul><li><a href="ol.source.TileSuperMapRest.html">TileSuperMapRest</a></li></ul><h3>Events</h3><ul><li><a href="module-xdh-map-type.html#~event:change">change</a></li><li><a href="module-xdh-map.html#~event:changeType">changeType</a></li><li><a href="module-xdh-map-pointer.html#~event:copy">copy</a></li><li><a href="module-xdh-map-draw.html#~event:drawend">drawend</a></li><li><a href="module-xdh-map-draw.html#~event:drawstart">drawstart</a></li><li><a href="module-xdh-map-draw.html#~event:modifyend">modifyend</a></li><li><a href="module-xdh-map-draw.html#~event:modifystart">modifystart</a></li><li><a href="module-xdh-map-track.html#~event:move">move</a></li><li><a href="module-xdh-map.html#~event:ready">ready</a></li><li><a href="module-xdh-map-track.html#~event:start">start</a></li><li><a href="module-xdh-map-track.html#~event:stop">stop</a></li></ul><h3>Global</h3><ul><li><a href="global.html#bd09ToGcj02">bd09ToGcj02</a></li><li><a href="global.html#bd09ToGps84">bd09ToGps84</a></li><li><a href="global.html#bd09ToWgs84">bd09ToWgs84</a></li><li><a href="global.html#capitalize">capitalize</a></li><li><a href="global.html#convertToWgs84">convertToWgs84</a></li><li><a href="global.html#createLayer">createLayer</a></li><li><a href="global.html#createTdtLayer">createTdtLayer</a></li><li><a href="global.html#D2R">D2R</a></li><li><a href="global.html#featureStyleRender">featureStyleRender</a></li><li><a href="global.html#gcj02ToBd09">gcj02ToBd09</a></li><li><a href="global.html#gcj02ToWgs84">gcj02ToWgs84</a></li><li><a href="global.html#gcjToGps84">gcjToGps84</a></li><li><a href="global.html#get">get</a></li><li><a href="global.html#getDistance">getDistance</a></li><li><a href="global.html#getParent">getParent</a></li><li><a href="global.html#gps84ToGcj02">gps84ToGcj02</a></li><li><a href="global.html#keyMap">keyMap</a></li><li><a href="global.html#LAYERS">LAYERS</a></li><li><a href="global.html#mapReady">mapReady</a></li><li><a href="global.html#mix">mix</a></li><li><a href="global.html#mixProps">mixProps</a></li><li><a href="global.html#options">options</a></li><li><a href="global.html#outOfChina">outOfChina</a></li><li><a href="global.html#pi">pi</a></li><li><a href="global.html#prefix">prefix</a></li><li><a href="global.html#props">props</a></li><li><a href="global.html#set">set</a></li><li><a href="global.html#StyleMap">StyleMap</a></li><li><a href="global.html#wgs84ToBd09">wgs84ToBd09</a></li><li><a href="global.html#wgs84ToGcj02">wgs84ToGcj02</a></li></ul>
</nav>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue May 21 2019 17:27:18 GMT+0800 (中国标准时间)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
